package test.register;

import org.I0Itec.zkclient.IZkStateListener;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.Watcher;

/**
 * Created by huang on 2018/2/6.
 */
public class ZkRegister {

    private static final String SERVER_TYPE_SERVER="server";
    private static final String SERVER_TYPE_SERVER_UNAVLID="server_unavlid";
    private static final String SERVER_TYPE_CLIENT="client";
    private static final String SERVER_TYPE_CLIENT_UNAVLID="client_unavlid";
    private static final String SERVER_CONFIG_PATH="/xingheservices";
    private static final String SERVER_CONFIG_PATH_SPLIT="/";


    private ServerRegisterProperties properties;

    private ZkClient zkClient;

    public ZkRegister(ServerRegisterProperties properties, ZkClient zkClient) {
        this.properties = properties;
        this.zkClient = zkClient;
    }

    public void autoRegister(){
        if(!zkClient.exists(SERVER_CONFIG_PATH)){
            zkClient.createPersistent(SERVER_CONFIG_PATH);
        }

        if(!zkClient.exists(SERVER_CONFIG_PATH +SERVER_CONFIG_PATH_SPLIT+properties.getGroupName())){
            zkClient.createPersistent(properties.getGroupName());
        }

        if(!zkClient.exists(SERVER_CONFIG_PATH +SERVER_CONFIG_PATH_SPLIT+properties.getGroupName()+SERVER_CONFIG_PATH_SPLIT+properties.getServerName())){
            zkClient.createPersistent(SERVER_CONFIG_PATH +SERVER_CONFIG_PATH_SPLIT+properties.getGroupName()+SERVER_CONFIG_PATH_SPLIT+properties.getServerName());
        }

        //删除不可用服务
        removeUnavlidServer(properties);
        //删除旧服务
        removeOldServer(properties);
        //注册新服务
        registeServer(properties);

        //处理链接重连问题
        zkClient.subscribeStateChanges(new IZkStateListener() {
            @Override
            public void handleStateChanged(Watcher.Event.KeeperState keeperState) throws Exception {

            }

            @Override
            public void handleNewSession() throws Exception {
                doRegisterAgain();
            }

            @Override
            public void handleSessionEstablishmentError(Throwable throwable) throws Exception {

            }
        });
    }

    private void doRegisterAgain() {
        //删除不可用服务
        removeUnavlidServer(properties);
        //删除旧服务
        removeOldServer(properties);
        //注册新服务
        registeServer(properties);
    }

    /**
     * 注册新服务
     * @param properties
     */
    private void registeServer(ServerRegisterProperties properties) {
        createNode(properties.getServerUrl(),properties.getServerType());
    }

    /**
     * 删除旧服务
     * @param properties
     */
    private void removeOldServer(ServerRegisterProperties properties) {
        removeNode(properties.getServerUrl(),properties.getServerType());
    }

    /**
     * 删除不可用服务
     * @param properties
     */
    private void removeUnavlidServer(ServerRegisterProperties properties) {
        removeNode(properties.getServerUrl(),SERVER_TYPE_SERVER_UNAVLID);
    }

    /**
     * 获取服务注册路径
     * @return
     */
    private String getFullPath(){
        return SERVER_CONFIG_PATH +SERVER_CONFIG_PATH_SPLIT+properties.getGroupName()+SERVER_CONFIG_PATH_SPLIT+properties.getServerName();
    }

    private void createNode(String url, String nodeType) {
        String nodeTypePath = getFullPath()+SERVER_CONFIG_PATH_SPLIT+nodeType;
        if (!zkClient.exists(nodeTypePath)) {
            zkClient.createPersistent(nodeTypePath, true);
        }
        zkClient.createEphemeral( nodeTypePath+SERVER_CONFIG_PATH_SPLIT+url, url);
    }

    private void removeNode(String url, String nodeType) {
        String nodePath =  getFullPath()+SERVER_CONFIG_PATH_SPLIT+nodeType;
        if (zkClient.exists(nodePath+SERVER_CONFIG_PATH_SPLIT+url)) {
            zkClient.delete(nodePath+SERVER_CONFIG_PATH_SPLIT+url);
        }
    }

}
